# !/usr/bin/env python3
# -*- coding: utf-8 -*-

import socket
import xml.etree.ElementTree as EleTree
from typing import List, Dict, Union
import math
import os
from util.json_utils import xml_file_to_json_file


def update_xml(conf_xml,
               addr_and_value_set: List[Dict[str, Union[str, List[str]]]],
               link: dict) -> None:
    tree = EleTree.parse(conf_xml)
    root = tree.getroot()

    node = EleTree.Element("node")
    node_child = EleTree.SubElement(node, "hcp_mid")
    node_id = link['src_node']
    node_child.text = str(node_id)

    # 将“地址-值”对写入xml文件
    for item in addr_and_value_set:
        node_child = EleTree.SubElement(node, "entry")
        node_child_addr = EleTree.SubElement(node_child, "addr")
        node_child_addr.text = item['addr']
        # print(type(item['addr']))
        value_set = item['value']
        # value_set的类型必须是列表
        if type(value_set) != list:
            print("error in tsn_builder_assembler\\lib.py. "
                  "Check the type of value_set.")
            exit(0)
        for value in value_set:
            # print(type(value))
            node_child_value = EleTree.SubElement(node_child, 'data')
            node_child_value.text = value

    root.append(node)
    tree = EleTree.ElementTree(root)
    pretty_xml(root, '\t', '\n')  # 执行美化方法
    tree.write(conf_xml,
               encoding='utf-8',
               xml_declaration=True)


# element为传进来的Element类，参数indent用于缩进，newline用于换行
def pretty_xml(element, indent, newline, level=0):
    if element is not None:  # 判断element是否有子元素
        # print(element.text)
        if (element.text is None) or element.text.isspace():  # 如果element的text没有内容
            element.text = newline + indent * (level + 1)
        else:
            element.text = element.text.strip()
    temp = list(element)  # 将element转成list
    for sub_element in temp:
        # 如果不是list的最后一个元素，说明下一个行是同级别元素的起始，缩进应一致
        if temp.index(sub_element) < (len(temp) - 1):
            sub_element.tail = newline + indent * (level + 1)
        else:  # 如果是list的最后一个元素， 说明下一行是母元素的结束，缩进应该少一个
            sub_element.tail = newline + indent * level
        # 对子元素进行递归操作
        pretty_xml(sub_element, indent, newline, level=level + 1)


def get_node_type(para_xml):
    """
    根据para_xml，获取节点类型，0为交换机，1为网卡，2为传感器，3为测试仪
    """
    node_type_set = []
    tree = EleTree.parse(para_xml)
    node_ele_set = tree.findall('node')
    for node_ele in node_ele_set:
        node_id = node_ele.findtext('node_id')
        node_type = node_ele.findtext('node_type')
        node_type_set.append({
            'node_id': int(node_id),
            'node_type': int(node_type, 16)
        })
    return node_type_set


def compute_time_slot_num(sched_period, time_slot_len):
    # 计算总的时间槽数目
    total_slot_num = math.ceil(sched_period / time_slot_len)

    return total_slot_num


def transfor_data_set_to_node_set(data_set):
    node_id_set = []
    for data_ele in data_set:
        node_id = data_ele['node_id']
        if node_id not in node_id_set:
            node_id_set.append(node_id)

    node_set = [{'node_id': node_id, 'data_set': []} for node_id in node_id_set]

    for data_ele in data_set:
        node_id = data_ele['node_id']
        for node in node_set:
            if node['node_id'] == node_id:
                del data_ele['node_id']
                node['data_set'].append(data_ele)
                break
    return node_set


 # def link_func_xml(self):
 #        self.ui.contentStackedWidget.setCurrentIndex(4)
 #        if self.linkFlag:
 #            reg_addr_xml = '../conf/addr_define.xml'
 #            file_path = '../input/'
 #            topo_xml = file_path + 'topo_feature.xml'
 #            output_tbl_path = '../output/tbl/'
 #            fwd_tbl_xml = output_tbl_path + 'fwd_tbl.xml'
 #            para_tbl_xml = output_tbl_path + 'para_tbl.xml'
 #            gcl_tbl_xml = output_tbl_path + 'gcl_tbl.xml'
 #            map_tbl_xml = output_tbl_path + 'map_tbl.xml'
 #            inject_tbl_xml = output_tbl_path + 'inject_tbl.xml'
 #            mac_tbl_xml = output_tbl_path + 'mac_tbl.xml'
 #            cb_tbl_xml = output_tbl_path + 'cb_tbl.xml'
 #            test_aux_tbl_xml = output_tbl_path + 'test_aux_tbl.xml'
 #            forward_mode_tbl_xml = output_tbl_path + 'forward_mode_tbl.xml'
 #            inform_tbl_xml = '../output/fl_api/inform_tbl.xml'
 #            conf_xml = '../output/tsnlight_plan_config.xml'
 #
 #            link(reg_addr_xml,
 #                 topo_xml,
 #                 fwd_tbl_xml,
 #                 para_tbl_xml,
 #                 gcl_tbl_xml,
 #                 map_tbl_xml,
 #                 inform_tbl_xml,
 #                 inject_tbl_xml,
 #                 mac_tbl_xml,
 #                 cb_tbl_xml,
 #                 test_aux_tbl_xml,
 #                 forward_mode_tbl_xml,
 #                 conf_xml)
 #
 #            # 将文件内容转成html语言
 #            with open(conf_xml, 'r') as f:
 #                line = f.readline()
 #                while line:
 #                    # 首先处理头和尾部的注释
 #                    if 'xml version' in line:
 #                        s = "<p><code><font color=blue>&lt;?</font><font color=#F4A460>xml version</font>" \
 #                            "<font color=\"#9ACD32\">='1.0' </font>" \
 #                            "<font color=\"#F4A460\">encoding</font>" \
 #                            "<font color=\"#9ACD32\">='utf-8'</font>" \
 #                            "<font color=blue>?&gt;</font></code></p>"
 #                    # 处理内容部分
 #                    else:
 #                        # 数该行文字有几个<标签
 #                        line = line.split()[0]
 #                        line = line.split('>')
 #                        # <标签的个数
 #                        gt_cnt = len(line) - 1
 #                        # print(gt_cnt)
 #                        # 该行是没有数据，只有标签的行
 #                        if gt_cnt == 1:
 #                            # 判断是否有/标签
 #                            line = line[0].split('<')[1]
 #                            if '/' in line:
 #                                if line[1:] == 'network_plan_cfg':
 #                                    s = "<p><code><font color=blue>&lt;/</font>" \
 #                                        "<font color=red>%s</font>" \
 #                                        "<font color=blue>&gt;</font></code></p>" % line[1:]
 #                                elif line[1:] == 'node':
 #                                    s = "<p><code><font color=blue>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/</font>" \
 #                                        "<font color=red>%s</font>" \
 #                                        "<font color=blue>&gt;</font></code></p>" % line[1:]
 #                                elif line[1:] == 'entry':
 #                                    s = "<p><code><font color=blue>&nbsp;&nbsp;&nbsp;&nbsp;" \
 #                                        "&nbsp;&nbsp;&nbsp;&nbsp;&lt;/</font>" \
 #                                        "<font color=red>%s</font>" \
 #                                        "<font color=blue>&gt;</font></code></p>" % line[1:]
 #
 #                            elif '/' not in line[0]:
 #                                if line == 'network_plan_cfg':
 #                                    s = "<p><code><font color=blue>&lt;</font>" \
 #                                        "<font color=red>%s</font>" \
 #                                        "<font color=blue>&gt;</font></code></p>" % line
 #                                elif line == 'node':
 #                                    s = "<p><code><font color=blue>&nbsp;&nbsp;&nbsp;&nbsp;&lt;</font>" \
 #                                        "<font color=red>%s</font>" \
 #                                        "<font color=blue>&gt;</font></code></p>" % line
 #                                elif line == 'entry':
 #                                    s = "<p><code><font color=blue>&nbsp;&nbsp;&nbsp;&nbsp;" \
 #                                        "&nbsp;&nbsp;&nbsp;&nbsp;&lt;</font>" \
 #                                        "<font color=red>%s</font>" \
 #                                        "<font color=blue>&gt;</font></code></p>" % line
 #                        elif gt_cnt == 2:
 #                            # 首先提取出标签
 #                            label = line[0].split("<")[1]
 #                            data = line[1].split('<')[0]
 #                            if label == 'hcp_mid':
 #                                s = "<p><code><font color=blue>&nbsp;&nbsp;&nbsp;&nbsp;" \
 #                                    "&nbsp;&nbsp;&nbsp;&nbsp;&lt;</font>" \
 #                                    "<font color=red>%s</font>" \
 #                                    "<font color=blue>&gt;</font>" \
 #                                    "<font color=black>%s</font>" \
 #                                    "<font color=blue>&lt;/</font><font color=red>%s</font>" \
 #                                    "<font color=blue>&gt;</font></code></p>" % (label, data, label)
 #                            else:
 #                                s = "<p><code><font color=blue>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" \
 #                                    "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;</font>" \
 #                                    "<font color=red>%s</font>" \
 #                                    "<font color=blue>&gt;</font>" \
 #                                    "<font color=black>%s</font>" \
 #                                    "<font color=blue>&lt;/</font>" \
 #                                    "<font color=red>%s</font>" \
 #                                    "<font color=blue>&gt;</font></code></p>" % (label, data, label)
 #
 #                    self.ui.linkTextBrowser.append(s)
 #                    line = f.readline()
 #            # 当前结果是最新结果，无需再次计算
 #            self.linkFlag = False
 #            self.ui.saveButton.setEnabled(True)
 #
 #            # 将conf_xml转成conf_json
 #            xml_file_to_json_file(conf_xml)
 #            # 删除conf_xml
 #            os.remove(conf_xml)
 #
 #            # # 删除指定文件夹中所有的xml文件
 #            # remove_path = '../input/'
 #            # for file_name in listdir(remove_path):
 #            #     if file_name.endswith('.xml'):
 #            #         os.remove(remove_path + file_name)
 #            #
 #            # remove_path = '../output/tbl/'
 #            # for file_name in listdir(remove_path):
 #            #     if file_name.endswith('.xml'):
 #            #         os.remove(remove_path + file_name)
 #            #
 #            # remove_path = '../output/fl_api/'
 #            # for file_name in listdir(remove_path):
 #            #     if file_name.endswith('.xml'):
 #            #         os.remove(remove_path + file_name)

